﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using TimeTable.Domain.DataAccess;
using TimeTable.Domain.Entity;

namespace TimeTable.AddForms
{
    public partial class NewTimeTableUnitForm : Form
    {
        public NewTimeTableUnitForm()
        {
            InitializeComponent();

            timeTable.DataSource = DataAccessConnection.Instance.GetAllTimeTables();
            studyUnit.DataSource = DataAccessConnection.Instance.GetAllStudyUnits();
            teacher.DataSource = DataAccessConnection.Instance.GetAllTeachers();
            room.DataSource = DataAccessConnection.Instance.GetAllRooms();

            dayOfWeekComboBox.DataSource = new List<DayOfWeek>
            {
                DayOfWeek.Monday,
                DayOfWeek.Tuesday,
                DayOfWeek.Wednesday,
                DayOfWeek.Thursday,
                DayOfWeek.Friday,
                DayOfWeek.Saturday
            };

            beginTime.Value = new DateTime(2013, 1, 1, 8, 0, 0);
            endTime.Value = new DateTime(2013, 1, 1, 9, 30, 0);
        }

        private void CancelButtonClick(object sender, EventArgs e)
        {
            Close();
        }

        private void OKButtonClick(object sender, EventArgs e)
        {
            try
            {
                if (string.IsNullOrEmpty(subject.Text)) throw new Exception("Subject can not be empty!");

                var selectedTimeTable = timeTable.SelectedItem as Domain.Entity.TimeTable;
                if (selectedTimeTable == null) throw new Exception("Please select time table!");

                var selectedStudyUnit = studyUnit.SelectedItem as StudyUnit;
                if (selectedStudyUnit == null) throw new Exception("Please select study unit!");

                var selectedTeacher = teacher.SelectedItem as Teacher;
                if (selectedTeacher == null) throw new Exception("Please select teacher!");

                var selectedRoom = room.SelectedItem as Room;
                if (selectedRoom == null) throw new Exception("Please select room!");

                if (beginTime.Value >= endTime.Value) throw new Exception("Please choose correct time!");

                if (selectedStudyUnit.StudentsNumber > selectedRoom.Capacity) throw new Exception("Selected room can not accommodate " + selectedStudyUnit.StudentsNumber + " students!");

                var selectedDayOfWeek = (DayOfWeek)dayOfWeekComboBox.SelectedItem;

                CheckRoomOccupied(selectedRoom, selectedDayOfWeek);
                CheckTeacherOccupied(selectedTeacher, selectedDayOfWeek);
                CheckTeacherWorkHours(selectedTeacher, selectedDayOfWeek);

                var timeTableUnit = new TimeTableUnit
                {
                    Subject = subject.Text,
                    TimeTable = selectedTimeTable,
                    StudyUnit = selectedStudyUnit,
                    Teacher = selectedTeacher,
                    Room = selectedRoom,
                    BeginTime = beginTime.Value,
                    EndTime = endTime.Value,
                    DayOfWeek = selectedDayOfWeek
                };

                if (DataAccessConnection.Instance.TimeTableUnitExists(timeTableUnit))
                {
                    MessageBox.Show("Course already exists!");
                }
                else
                {
                    DataAccessConnection.Instance.AddTimeTableUnit(timeTableUnit);

                    MessageBox.Show("Course successfully added!");

                    Close(); 
                }
            }
            catch(Exception exception)
            {
                MessageBox.Show(exception.Message, "Error");
            }
        }

        private void CheckRoomOccupied(Room currentRoom, DayOfWeek dayOfWeek)
        {
            var units = DataAccessConnection.Instance.GetTimeTableUnitsByRoom(currentRoom);

            foreach (var unit in units)
            {
                if (unit.DayOfWeek == dayOfWeek && (beginTime.Value >= unit.BeginTime && beginTime.Value <= unit.EndTime || endTime.Value >= unit.BeginTime && endTime.Value <= unit.EndTime))
                {
                    throw new Exception("Selected room is already occupied on selected time interval!");
                }
            }
        }

        private void CheckTeacherOccupied(Teacher currentTeacher, DayOfWeek dayOfWeek)
        {
            var units = DataAccessConnection.Instance.GetTimeTableUnitsByTeacher(currentTeacher);

            foreach (var unit in units)
            {
                if (unit.DayOfWeek == dayOfWeek && (beginTime.Value >= unit.BeginTime && beginTime.Value <= unit.EndTime || endTime.Value >= unit.BeginTime && endTime.Value <= unit.EndTime))
                {
                    throw new Exception("Selected teacher is already busy on selected time interval!");
                }
            }
        }

        private void CheckTeacherWorkHours(Teacher currentTeacher, DayOfWeek dayOfWeek)
        {
            var units = DataAccessConnection.Instance.GetTimeTableUnitsByTeacher(currentTeacher);

            var timeSpan = TimeSpan.FromHours(0);

            foreach (var unit in units)
            {
                if (unit.DayOfWeek == dayOfWeek)
                {
                    timeSpan += (unit.EndTime - unit.BeginTime);
                }
            }

            if (timeSpan.Hours + (endTime.Value - beginTime.Value).Hours > 8)
            {
                throw new Exception("Selected teacher cant work more than 8 hours per day!");
            }
        }
    }
}
